package tpase.GlobalServer.DAO;

import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import tpase.GlobalServer.DO.GroupGenerator;
import tpase.util.JDBCUtil;
import tpase.util.Util;

import java.io.ByteArrayInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class GroupGeneratorDao {
    public void clearGroupGenerator() {
        Connection connection = JDBCUtil.getConnect();
        String sql = "DELETE FROM group_generator";
        PreparedStatement statement = null;
        try {
            statement = connection.prepareCall(sql);
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement);
        }
    }

    public void storeGroupGenerator(GroupGenerator groupGenerator) {
        Connection connection = JDBCUtil.getConnect();
        String sql = "INSERT INTO group_generator (name, value) VALUES (?, ?)";
        PreparedStatement statement = null;
        try {
            statement = connection.prepareCall(sql);
            byte[] bytes = groupGenerator.getValue();
            statement.setString(1, groupGenerator.getName());
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream((bytes));
            statement.setBinaryStream(2, byteArrayInputStream, bytes.length);
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement);
        }
    }

    public void storeGroupGenerator(List<GroupGenerator> groupGeneratorList) {
        Connection connection = JDBCUtil.getConnect();
        String sql = "INSERT INTO group_generator (name, value) VALUES (?, ?)";
        PreparedStatement statement = null;
        try {
            statement = connection.prepareStatement(sql);
            for (GroupGenerator groupGenerator : groupGeneratorList) {
                byte[] bytes = groupGenerator.getValue();
                statement.setString(1, groupGenerator.getName());
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream((bytes));
                statement.setBinaryStream(2, byteArrayInputStream, bytes.length);
                statement.addBatch();
            }
            statement.executeBatch();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement);
        }
    }

    /**
     * 通过生成元名称查询生成元的字节数组
     */
    public byte[] getGeneratorByName(String name) {
        Connection connection = JDBCUtil.getConnect();
        String sql = "SELECT value FROM group_generator WHERE name = ?";
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        byte[] res = null;
        try {
            statement = connection.prepareCall(sql);
            statement.setString(1, name);
            resultSet = statement.executeQuery();
            if (resultSet.next()) {
                res = resultSet.getBytes("value");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement, resultSet);
        }
        if (res == null) {
            throw new RuntimeException("getGeneratorByName, 生成元查询结果为空");
        }
        return res;
    }

    public List<GroupGenerator> getGroupGenerator() {
        Connection connection = JDBCUtil.getConnect();
        String sql = "SELECT name, value FROM group_generator";
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        List<GroupGenerator> groupGeneratorList = new ArrayList<>();
        try {
            statement = connection.prepareCall(sql);
            resultSet = statement.executeQuery();
            while (resultSet.next()) {
                String name = resultSet.getString("name");
                byte[] value = resultSet.getBytes("value");
                groupGeneratorList.add(new GroupGenerator(name, value));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement, resultSet);
        }
        return groupGeneratorList;
    }

    public static void main(String[] args) {
        final String jpbcPath = "config/a.properties";
        Pairing pairing = Util.getPairing(jpbcPath);
//        GroupGeneratorDao groupGeneratorDao = new GroupGeneratorDao();
//        groupGeneratorDao.clearGroupGenerator();
//
//        Element element = Util.getPairing(jpbcPath).getZr().newRandomElement();
//        List<GroupGenerator> list = new ArrayList<>();
//        list.add(new GroupGenerator("1", element.toBytes()));
//        list.add(new GroupGenerator("2", element.toBytes()));
//        groupGeneratorDao.storeGroupGenerator(list);
//
//
//        byte[] bytes = groupGeneratorDao.getGeneratorByName("1");
//        Element element2 = Util.getPairing(jpbcPath).getZr().newElementFromBytes(bytes);
//        System.out.println(element2.toString());

        GroupGeneratorDao groupGeneratorDao = new GroupGeneratorDao();
        List<GroupGenerator> list = groupGeneratorDao.getGroupGenerator();
        for (GroupGenerator groupGenerator : list) {
            System.out.println(groupGenerator.getName() + ", " + pairing.getZr().newElementFromBytes(groupGenerator.getValue()));
        }
    }

}
